package com.samcai.swiperecyclerview.adapter;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;

import com.samcai.swiperecyclerview.holder.RecyclerViewHolder;
import com.samcai.swiperecyclerview.imp.RecyclerAdapterImp;
import com.samcai.swiperecyclerview.listener.OnItemClickListener;
import com.samcai.swiperecyclerview.listener.OnItemLongClickListener;
import com.samcai.swiperecyclerview.listener.OnItemSelectedListener;
import com.samcai.swiperecyclerview.listener.OnSubItemClickListener;
import com.samcai.swiperecyclerview.view.CustomRecyclerView;
import com.samcai.swiperecyclerview.view.ItemView;
import com.samcai.swiperecyclerview.view.LoaderView;


public class RecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> implements RecyclerAdapterImp<T> {

	private Context mContext;

	private LoaderView mLoaderView;

	private View mItemView;

	private View mHeaderView;

	private View mFooterView;

	/**
	 * 继承ItemView的类的类类型
	 */
	private Class<?> mViewClass;

	/**
	 * ItemView数据源
	 */
	private List<T> mDatas;

	/**
	 * 触发SubView点击事件的子view ID
	 */
	private int mSubViewId;

	/**
	 * 记录选中的ItemView
	 */
	private SparseBooleanArray mSelectedItems;

	private OnItemClickListener mOnItemClickListener;

	private OnItemSelectedListener mOnItemSelectedListener;

	private OnItemLongClickListener mOnItemLongClickListener;

	private OnSubItemClickListener mOnSubItemClickListener;

	@Override
	public final void setOnItemClickListener(OnItemClickListener listener) {

		mOnItemClickListener = listener;
	}

	@Override
	public final void setOnItemSelectedListener(OnItemSelectedListener listener) {

		mOnItemSelectedListener = listener;
	}

	@Override
	public final void setOnItemLongClickListener(OnItemLongClickListener listener) {

		mOnItemLongClickListener = listener;
	}

	@Override
	public final void setOnSubItemClickListener(int subViewId, OnSubItemClickListener listener) {

		mOnSubItemClickListener = listener;
		mSubViewId = subViewId;
	}

	/**
	 * Adapter构造函数
	 * 
	 * @param context
	 *            上下文
	 * @param datas
	 *            ItemView数据源
	 * @param viewClass
	 *            -->带@EViewGroup注解的类的衍生类的类类型
	 *            例如带@EViewGroup注解的类MItemView，应传入MItemView_.class
	 */
	public RecyclerViewAdapter(Context context, List<T> datas, Class<?> viewClass) {

		if (context != null) {
			mContext = context;
		}
		//
		if (datas != null) {
			mDatas = datas;
		} else {
			mDatas = new ArrayList<T>();
		}
		//
		if (viewClass != null) {
			mViewClass = viewClass;
		}
		//
		mSelectedItems = new SparseBooleanArray();
	}

	/**
	 * Adapter构造函数，需要复写onCreateItemView(int viewType)方法
	 * 
	 * @param context
	 *            上下文
	 */
	public RecyclerViewAdapter(Context context) {

		this(context, null, null);
	}

	/**
	 * Adapter构造函数，需要复写onCreateItemView(int viewType)方法
	 * 
	 * @param context
	 *            上下文
	 * @param viewClass
	 *            -->带@EViewGroup注解的类的衍生类的类类型
	 *            例如带@EViewGroup注解的类MItemView，应传入MItemView_.class
	 */
	public RecyclerViewAdapter(Context context, Class<?> viewClass) {

		this(context, null, viewClass);
	}

	/**
	 * Adapter构造函数，需要复写onCreateItemView(int viewType)方法
	 * 
	 * @param context
	 *            上下文
	 * @param datas
	 *            ItemView数据源
	 */
	public RecyclerViewAdapter(Context context, List<T> datas) {

		this(context, datas, null);
	}

	/**
	 * 根据getItemViewType(int position)的返回值viewType返回对应的View
	 * 
	 * @time 2016年2月3日下午4:42:19
	 * @see android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder(android.view.ViewGroup,
	 *      int)
	 * @describe [nothing]
	 */
	@Override
	public final RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

		//
		if (viewType == CustomRecyclerView.VIEW_TYPE_HEADER) {
			return new RecyclerViewHolder(mHeaderView);
		}
		if (viewType == CustomRecyclerView.VIEW_TYPE_FOOTER) {
			return new RecyclerViewHolder(mFooterView);
		}
		if (viewType == CustomRecyclerView.VIEW_TYPE_LOAD_STATE_VIEW) {
			return new RecyclerViewHolder(mLoaderView);
		}

		//
		return onCreateItemView(viewType);
	}

	@Override
	public RecyclerViewHolder onCreateItemView(int viewType) {

		if (mViewClass != null) {
			try {
				Method build = mViewClass.getMethod("build", Context.class);
				mItemView = (View) build.invoke(mViewClass, mContext);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return new RecyclerViewHolder(mItemView);
		}
		return null;
	}

	@Override
	public final void onBindViewHolder(RecyclerViewHolder holder, int position) {

		if (holder == null) {
			return;
		}

		View view = holder.getView();

		if (view instanceof ItemView) {
			@SuppressWarnings("unchecked")
			ItemView<T> itemView = (ItemView<T>) view;
			// 绑定数据
			itemView.bind(mDatas.get(position - ((mHeaderView != null) ? 1 : 0)));
		}

		// 绑定监听事件
		bindListener(holder, position);
	}

	@Override
	public final int getItemCount() {

		return mDatas.size() + ((mHeaderView != null) ? 1 : 0) + ((mFooterView != null) ? 1 : 0) + ((mLoaderView != null) ? 1 : 0);
	}

	/**
	 * 一般请不要复写此方法，设置itemViewType请复写setItemViewType(int position)方法
	 * 
	 * @time 2016年2月3日下午4:45:03
	 * @see android.support.v7.widget.RecyclerView.Adapter#getItemViewType(int)
	 * @describe [nothing]
	 */
	@Override
	public final int getItemViewType(int position) {

		if (position == 0 && mHeaderView != null) {
			return CustomRecyclerView.VIEW_TYPE_HEADER;
		}

		if (position == getItemCount() - 1 && mLoaderView != null) {
			return CustomRecyclerView.VIEW_TYPE_LOAD_STATE_VIEW;
		}

		if (position == getItemCount() - 1 && mLoaderView == null && mFooterView != null) {
			return CustomRecyclerView.VIEW_TYPE_FOOTER;

		} else if (position == getItemCount() - 2 && mLoaderView != null && mFooterView != null) {
			return CustomRecyclerView.VIEW_TYPE_FOOTER;
		}

		return setItemViewType(position - (mHeaderView != null ? 1 : 0));
	}

	@Override
	public int setItemViewType(int position) {

		return 0;
	}

	@Override
	public final void setHeaderView(View headerView) {

		mHeaderView = headerView;
		notifyDataSetChanged();
	}

	@Override
	public final void setFooterView(View footerView) {

		mFooterView = footerView;
		notifyDataSetChanged();
	}

	@Override
	public final void setLoaderView(LoaderView loaderView) {

		mLoaderView = loaderView;
		notifyDataSetChanged();
	}

	@Override
	public final void setData(T data) {

		mDatas.clear();
		mDatas.add(data);
		notifyDataSetChanged();
	}

	@Override
	public final void setData(List<T> datas) {

		mDatas = datas;
		notifyDataSetChanged();
	}

	@Override
	public final void addData(T data) {

		mDatas.add(data);
		notifyDataSetChanged();
	}

	@Override
	public final void addData(int position, T data) {

		mDatas.add(position, data);
		notifyDataSetChanged();
	}

	@Override
	public final void addData(List<T> datas) {

		mDatas.addAll(datas);
		notifyDataSetChanged();
	}

	@Override
	public final void addData(int position, List<T> datas) {

		mDatas.addAll(position, datas);
		notifyDataSetChanged();
	}

	@Override
	public final T getData(int position) {

		return mDatas.get(position);
	}

	@Override
	public final List<T> getData() {

		return mDatas;
	}

	@Override
	public final void removeData(int position) {

		mDatas.remove(position);
		notifyDataSetChanged();
	}

	/**
	 * 绑定监听器
	 * 
	 * @time 2016年2月15日上午9:34:43
	 * @param holder
	 * @param position
	 */
	private void bindListener(final RecyclerViewHolder holder, final int position) {

		//
		int viewType = getItemViewType(position);
		// 除去HeaderView
		final int fixPosition = position - (mHeaderView != null ? 1 : 0);
		//
		if (viewType == CustomRecyclerView.VIEW_TYPE_LOAD_STATE_VIEW
				|| viewType == CustomRecyclerView.VIEW_TYPE_HEADER || viewType == CustomRecyclerView.VIEW_TYPE_FOOTER) {
			return;
		}

		// 点击事件、选择事件，选择事件将覆盖点击事件
		if (mOnItemClickListener != null || mOnItemSelectedListener != null) {
			//
			holder.itemView.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {

					// 点击事件
					if (mOnItemSelectedListener == null && mOnItemClickListener != null) {
						mOnItemClickListener.onItemClick(v, fixPosition, mDatas.get(fixPosition));
						return;
					}

					// 当选择事件启用时，点击事件不被触发
					if (mSelectedItems.size() == 0) {
						// 第一次触发选中
						mSelectedItems.append(fixPosition, true);
						mOnItemSelectedListener.onItemSelected(v, fixPosition, mDatas.get(fixPosition));

					} else if (mSelectedItems.get(fixPosition, false)) {
						// 取消选中
						mSelectedItems.delete(fixPosition);
						//
						if (mSelectedItems.size() == 0) {
							// 没有被选中的
							mOnItemSelectedListener.onNothingSelected(v, fixPosition, mDatas.get(fixPosition));
						} else {
							mOnItemSelectedListener.onItemUnselected(v, fixPosition, mDatas.get(fixPosition));
						}
					} else {
						// 选中
						mSelectedItems.append(fixPosition, true);
						mOnItemSelectedListener.onItemSelected(v, fixPosition, mDatas.get(fixPosition));
					}
				}
			});
		}

		// 长按事件
		if (mOnItemLongClickListener != null) {
			//
			holder.itemView.setOnLongClickListener(new OnLongClickListener() {

				@Override
				public boolean onLongClick(View v) {

					mOnItemLongClickListener.onItemLongClick(v, fixPosition, mDatas.get(fixPosition));
					return true;
				}
			});
		}

		// 子控件点击事件
		if (mOnSubItemClickListener != null) {
			//
			View view = holder.itemView.findViewById(mSubViewId);
			//
			if (view != null) {
				view.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {

						mOnSubItemClickListener.onSubItemClick(v, fixPosition, mDatas.get(fixPosition));
					}
				});
			}
		}
	}

}
